package com.jt.utils;

import com.alibaba.fastjson.util.FieldInfo;
import com.jt.entity.ExcelField;
import com.jt.entity.ExcelFieldInfo;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class ExcelUtil {
    public static <T> void getExcel(List<T> dataList, String filePath, HttpServletResponse response) {
        if (dataList == null || dataList.isEmpty()) {
            throw new IllegalArgumentException("数据列表不能为空");
        }
        Class<?> aClass = dataList.get(0).getClass();
        List<ExcelFieldInfo> fieldInfo = getFieldInfo(aClass);
        OutputStream ouputStream = null;
        try {
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("sheet1");
            /*创建表头*/
            creatHeader(sheet, fieldInfo);
            /*设置表体*/
            creatDate(sheet, dataList, fieldInfo);
            // 在写入文件前添加目录和文件存在性检查
            Path path = Paths.get(filePath);
            Path parentDir = path.getParent();
            if (parentDir != null && !Files.exists(parentDir)) {
                Files.createDirectories(parentDir);
            }
            if (Files.exists(path)) {
                Files.delete(path);
            }
            response.addHeader("Content-Type", "application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("content-disposition", "attachment;filename=" + new String("???????".getBytes("ISO8859-1")));
            ouputStream = response.getOutputStream();
            workbook.write(ouputStream);
            workbook.write(Files.newOutputStream(path));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static <T> void creatDate(Sheet sheet, List<T> dataList, List<ExcelFieldInfo> fieldInfo) {
        for (int i = 0; i < dataList.size(); i++) {
            T t = dataList.get(i);
            Row row = sheet.createRow(i + 1);
            for (int j = 0; j < fieldInfo.size(); j++) {
                ExcelFieldInfo excelFieldInfo = fieldInfo.get(j);
                Field field = excelFieldInfo.getField();
                Object value = null;
                try {
                    value = field.get(t);
                    if (value == null) {
                        continue;
                    }
                    row.createCell(j).setCellValue(value.toString());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static List<ExcelFieldInfo> getFieldInfo(Class<?> clazz) {
        List<ExcelFieldInfo> fieldInfos = new ArrayList<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            ExcelField excelField = field.getAnnotation(ExcelField.class);
            if (excelField != null) {
                field.setAccessible(true);
                fieldInfos.add(new ExcelFieldInfo(field, excelField));
            }
        }
        return fieldInfos;
    }


    public static void creatHeader(Sheet sheet, List<ExcelFieldInfo> fieldInfo) {
        Row row0 = sheet.createRow(0);
        for (int i = 0; i < fieldInfo.size(); i++) {
            row0.createCell(i).setCellValue(fieldInfo.get(i).getExcelField().name());
        }
    }
}
